package com.qing.simple_player.player;

import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.media3.common.MediaItem;
import androidx.media3.common.Player;
import androidx.media3.session.MediaSession;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 播放器接口。
 */
public interface IPlayer {

    int PLAY_STATE_IDLE = Player.STATE_IDLE; // 空闲
    int PLAY_STATE_BUFFERING = Player.STATE_BUFFERING; // 缓冲
    int PLAY_STATE_READY = Player.STATE_READY; // 准备就绪
    int PLAY_STATE_ENDED = Player.STATE_ENDED; // 播放结束
    int PLAY_STATE_PLAYING = 0x05; // 播放中
    int PLAY_STATE_PAUSED = 0x06; // 暂停
    int PLAY_STATE_ERROR = 0x07; // 错误
    int PLAY_STATE_SEEKING = 0x08; // 跳转中

    @IntDef({PLAY_STATE_IDLE, PLAY_STATE_BUFFERING, PLAY_STATE_READY, PLAY_STATE_ENDED, PLAY_STATE_PLAYING, PLAY_STATE_PAUSED, PLAY_STATE_ERROR, PLAY_STATE_SEEKING})
    @Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
    @Retention(RetentionPolicy.SOURCE)
    @interface PlaySate {
    }

    @NonNull
    static String playStateToString(@PlaySate int state) {
        switch (state) {
            case PLAY_STATE_IDLE:
                return "IDLE";
            case PLAY_STATE_BUFFERING:
                return "BUFFERING";
            case PLAY_STATE_READY:
                return "READY";
            case PLAY_STATE_ENDED:
                return "ENDED";
            case PLAY_STATE_PLAYING:
                return "PLAYING";
            case PLAY_STATE_PAUSED:
                return "PAUSED";
            case PLAY_STATE_ERROR:
                return "ERROR";
            case PLAY_STATE_SEEKING:
                return "SEEKING";
            default:
                return "UNKNOWN";
        }
    }

    /**
     * 设置媒体项。
     *
     * @param mediaItem 媒体项。
     */
    void setMediaItem(@NonNull MediaItem mediaItem);

    /**
     * 设置媒体 URL。
     *
     * @param url 媒体 URL。
     */
    void setMediaUrl(@NonNull String url);

    /**
     * 设置多个媒体项。
     * 播放器不同，实现也会有差异，单个播放器时，添加到同一列表中，多播放器时分别添加到对应播放器中，具体功能看子类实现。
     *
     * @param mediaItems 媒体项数组。
     */
    void setMediaItems(@NonNull MediaItem... mediaItems);

    /**
     * 设置多个媒体 URL。
     *
     * @param urls 媒体 URL 数组。
     */
    void setMediaUrls(@NonNull String... urls);

    /**
     * 开始播放。
     */
    void play();

    /**
     * 暂停播放。
     */
    void pause();

    /**
     * 跳转到指定位置。
     *
     * @param positionMs 播放位置（毫秒）。
     */
    void seekTo(long positionMs);

    /**
     * 停止播放。
     */
    void stop();

    /**
     * 设置播放速度。
     *
     * @param speed 播放速度。
     */
    void setPlaybackSpeed(float speed);

    /**
     * 设置是否准备播放。
     *
     * @param playWhenReady 是否准备播放。
     */
    void setPlayWhenReady(boolean playWhenReady);

    /**
     * 获取当前播放位置。
     *
     * @return 当前播放位置（毫秒）。
     */
    long getCurrentPosition();

    /**
     * 获取当前播放总时长。
     *
     * @return 当前播放总时长（毫秒）。
     */
    long getDuration();

    /**
     * 释放播放器。
     */
    void release();

    /**
     * 获取媒体会话。
     *
     * @return 媒体会话。
     */
    @Nullable
    default MediaSession getMediaSession() {
        return null;
    }

    interface Listener extends Player.Listener {
        default void onProgressChanged(long positionMs, long durationMs) {
        }

        default void onPlayStateChanged(@PlaySate int state) {
        }
    }
}
